#include "board.h"
#include "muk_core.h"

pin_list_t *muk_scan_list;
mku_mode_t muk_scan_mode = MKU_COL_SCAN;
extern uint8_t select_num;
extern uint32_t drv_read_port(uint8_t port);
extern void activate_key_in_map(uint8_t row, uint8_t col);

mku_stat_t scan_init() {
    uint8_t *tmp;
    uint8_t size = (muk_scan_mode == MKU_COL_SCAN) ? KEY_COL_MAXSIZE
                                                   : KEY_ROW_MAXSIZE;

    tmp = krhino_mm_alloc(sizeof(uint8_t) * size);

    if (tmp == NULL) {
        return MKU_MATRIX_ERR;
    }
    
    muk_scan_list->len = 0;
    muk_scan_list->pins = tmp;
    return MKU_SUCCESS;
}

mku_stat_t scan_pin_add(uint8_t pin, uint8_t row_or_col) {
    if (muk_scan_list->len < KEY_ROW_MAXSIZE) {
        muk_scan_list->pins[muk_scan_list->len] = pin;
        muk_scan_list->len++;
        return MKU_SUCCESS;
    } else {
        return MKU_MATRIX_ERR;
    }
}

void scan_port() {
    for (uint8_t port_num = 0; port_num <= GPIO_PORT_COUNT; port_num++) {
        uint32_t port_value = drv_read_port(port_num);
        if (port_value != 0) {
            for (uint8_t list_num = 0; list_num <= muk_scan_list->len;
                 list_num++) {
                if (PIN_IN_PORT(muk_scan_list->pins[list_num], port_num) &&
                    PIN_ACTIVE(muk_scan_list->pins[list_num], port_value)) {
                    switch (muk_scan_mode) {
                    case MKU_COL_SCAN:
                        activate_key_in_map(select_num, list_num);
                        break;
                    case MKU_ROW_SCAN:
                        activate_key_in_map(list_num, select_num);
                        break;
                    default:
                        break;
                    }
                }
            }
        }
    }
}
